package ar.com.equis.flexjavaintegration.utilidades;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import ar.com.equis.flexjavaintegration.excepciones.NoNegocioExcepcion;

public class ReflectonUtils {
	
	private static final String PREFIJO_GET = "get";
	
	public static Object ejecutarGetter(String nombreCampo,Object instancia){
		String nombreMetodoGetter = crearGetterNombre(nombreCampo);
		@SuppressWarnings("rawtypes")
		Class clase = obtenerClase(instancia.getClass().getName());
		Method metodo = obtenerMetodo(nombreMetodoGetter, clase);
		return ejecutarMetodo(instancia, metodo);
	}

	public static Object ejecutarMetodo(Object instancia, Method metodo) {
		try {
			return metodo.invoke(instancia, new Object[0]);
		} catch (IllegalArgumentException e) {
			throw new NoNegocioExcepcion("Los argumentos para el metodo: "+ metodo.getName()+ " no son del tipo correcto");
		} catch (IllegalAccessException e) {
			throw new NoNegocioExcepcion("Acceso ilegal al metodo: " + metodo.getName());
		} catch (InvocationTargetException e) {
			throw new NoNegocioExcepcion("Error al ejecutar  el metodo: " + metodo.getName());
		}
	}

	@SuppressWarnings("unchecked")
	public static Method obtenerMetodo(String nombreMetodo, @SuppressWarnings("rawtypes") Class clase){
		Method metodo;
		try {
			metodo = clase.getMethod(nombreMetodo, new Class[0]);
			return metodo;
		} catch (SecurityException e) {
			throw new NoNegocioExcepcion("No tiene acceso al metodo: " + nombreMetodo);
		} catch (NoSuchMethodException e) {
			throw new NoNegocioExcepcion("No existe el metodo:" + nombreMetodo);
		}
	}

	private static Class obtenerClase(String nombreClase) {
		Class clase;
		try {
			clase = Class.forName(nombreClase);
			return clase;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new NoNegocioExcepcion("No existe la clase de nombre: "
					+ nombreClase);
		}
	}

	public static String crearGetterNombre(String nombreCampo) {
		return  PREFIJO_GET + nombreCampo.substring(0, 1).toUpperCase() + nombreCampo.substring(1,nombreCampo.length());
	}
}
